package com.starinside.wp.controller.api.Template;

import com.alibaba.fastjson.JSON;
import com.starinside.wp.service.wx.VIPMpService;
import com.starinside.wp.config.WxMpProperties;
import com.starinside.wp.domain.Children;
import com.starinside.wp.domain.WxUser;
import com.starinside.wp.foundation.exception.BusinessException;
import com.starinside.wp.foundation.model.ErrorCode;
import com.starinside.wp.foundation.model.StatusResponse;
import com.starinside.wp.service.ChildrenService;
import com.starinside.wp.service.PortalService;
import com.starinside.wp.service.WxUserService;
import com.tuo51.foudation.utils.CopyUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.apache.commons.lang.StringUtils;
import org.beetl.ext.fn.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author Binary Wang(https://github.com/binarywang)
 */
@EnableConfigurationProperties(WxMpProperties.class)
@RestController
@RequestMapping("/wx/push")
@Slf4j
@Api(value = "/wx/push", tags = "微信模板消息推送接口")
public class WxPushController {

    @Autowired
    private WxMpProperties properties;

    @Autowired
    private WxMpService wxService;

    @Autowired
    private VIPMpService vipWxService;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    private PortalService portalService;

    @Autowired
    private ChildrenService childrenService;

    @Autowired
    private Environment environment;

    @RequestMapping(value = "/send/{channel}/{childrenId}",method = RequestMethod.POST)
    @ResponseBody
    protected StatusResponse send(@RequestBody WxTemplateVO template,
                                  @PathVariable String channel,
                                  @PathVariable String childrenId){

        if(StringUtils.isEmpty(channel) || !channel.equals(properties.getChannel()) ){
            return StatusResponse.error(ErrorCode.GENRAL_INTERNAL_ERROR, "channel not supported");
        }

        //根据areaid获取园区配置
        Children children = childrenService.getById(childrenId);
        if(children == null) {
            return StatusResponse.error(ErrorCode.CHILDREN_NOT_EXIST, "children not exist");
        }

        String areaId = children.getAreaId();
        String areaAppId = portalService.getMPAppId(areaId);
        String areaAppSecret = portalService.getMPAppSecret(areaId);

        String sourceAppId = null;
        boolean defaultSourceApp = true;
        //如果存在，则忽略其他的
        if(StringUtils.isNotEmpty(areaAppId)){
            if( StringUtils.isEmpty(areaAppSecret)){
                return StatusResponse.error(ErrorCode.GENRAL_INTERNAL_ERROR, "vip mp config failed");
            }
            //使用园区配置
            sourceAppId = areaAppId;
            defaultSourceApp = false;

            //园区appId生效，则使用园区模板id
            template.setTemplate_id(translateTemplateIdToVIPTemplateId(areaId, template.getTemplate_id()));

            //跳转地址重新设置
            template.setUrl(translateJumpURLToVipAreaURL(areaId, template.getUrl()));
        }else{
            //不存在则使用预置的appid
            //return StatusResponse.error(ErrorCode.WX_AREA_MP_CONFIG_FAILED, "园区areaId配置错误")
            sourceAppId = properties.getConfigs().get(0).getAppId();
        }

        List<WxUser> parents = wxUserService.findWxUserListByChildrenIdAndSourceAppId(childrenId, sourceAppId, defaultSourceApp);

        if(parents.size() == 0){
            log.warn("try to push a non-binding children " + childrenId + ">>>" + sourceAppId + ":::" + defaultSourceApp);
            return StatusResponse.success(new ArrayList<>());
        }

        String[] toUserIds = parents.stream().filter(o -> StringUtils.isNotEmpty(o.getParentMobile())).map(o -> {
            return o.getOpenidWp();
        }).toArray(String[]::new);

        String toUserIdsStr = StringUtils.join(toUserIds, ',');

        template.setTouser(toUserIdsStr);

        List<String> result = doSend(template, areaAppId, areaAppSecret);

        return StatusResponse.success(result);
    }

    private String translateTemplateIdToVIPTemplateId(String areaId, String officialTemplateId){
        Map<String, String> ids = portalService.getMpTemplateIds(areaId);
        String ret = ids.get(officialTemplateId);

        if(StringUtils.isEmpty(ret)){
            throw  new BusinessException(ErrorCode.UNDEFINED, "VIP template id not found");
        }

        return ret;
    }

    private String translateJumpURLToVipAreaURL(String areaId, String officialURL){
        if(StringUtils.isBlank(officialURL)){
            return officialURL;
        }

        //2c90805b6cacba9c016cbd62592e00f0.vip.mp.starinside.net
        //2c90805b6cacba9c016cbd62592e00f0.vip.mp.dev.starinside.net
        String officialHost = properties.getHost();
//        if(officialURL.indexOf(officialHost) > 0){
//            officialURL = officialURL.replace("//mp.", String.format("//%s.vip.mp.", areaId));
//        }
        if(officialURL.indexOf(officialHost) >= 0){
            officialURL = officialURL.replace("//mp.", String.format("//%s.vip.mp.", areaId));
            officialURL = officialURL.replace(".starinside.cn/", ".starinside.net/");
        }

        return officialURL;
    }

    /**
     * 通用模版接口，不涉及具体业务模版
     * @param template
     * @return
     */
    @RequestMapping(value = "/send",method = RequestMethod.POST)
    @ResponseBody
    protected StatusResponse send(@RequestBody WxTemplateVO template){
        log.info("template:send",template.toString());

        List<String> result = doSend(template, null, null);

        return StatusResponse.success(result);
    }

    @RequestMapping(value = "/send_test",method = RequestMethod.GET)
    public String doSendTestTemplate(){
        String titleStr = "回头客到访";
        String contentStr = "您有回头客到访，请及时接待，不要让顾客等太久哦~~";
        String dateStr = "2018-6-7 13:50";

        String touser = "oDqua1GIgQ-lhcDw-zKld7DoKZUs";
        String templat_id = "-A151xUddRaNvYv7iKuKPs9t4RwaPWq2D2XhE61Jygw";
        String clickurl = "http://www.baidu.com";
        String topcolor = "#FF0000";


        WxTemplate template = new WxTemplate();
        template.setTemplate_id(templat_id);
        template.setUrl(clickurl);
        template.setTouser(touser);

        WxTemplateItem title = new WxTemplateItem();
        title.setValue(titleStr);
        title.setColor(topcolor);
        title.setName("title");

        WxTemplateItem date = new WxTemplateItem();
        date.setValue(dateStr);
        date.setColor(topcolor);
        date.setName("date");

        WxTemplateItem content = new WxTemplateItem();
        content.setValue(contentStr);
        content.setColor(topcolor);
        content.setName("content");

        List<WxTemplateItem> items = new ArrayList<>();
        template.setData(items);

        items.add(title);
        items.add(date);
        items.add(content);

        doSend(template, null, null);

        return null;
    }

    private List<String> doSend(WxTemplateVO templateVO, String forceAppId, String forceAppSecret) {
        String json = templateVO.getData();
        templateVO.setData(null);

        WxTemplate template = new WxTemplate();
        CopyUtils.copyProperties(templateVO, template);

        if (StringUtils.isNotBlank(json)) {
            List<WxTemplateItem> items = JSON.parseArray(json, WxTemplateItem.class);
            if (items != null && items.size() > 0){
                template.setData(items);
            }
        }

        return doSend(template, forceAppId, forceAppSecret);
    }

    private List<String> doSend(WxTemplate template, String forceAppId, String forceAppSecret){
        String[] userList = template.getTouser().split(",");

        List<String> errList = new ArrayList<>();

        for (String user:userList){
            WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
            templateMessage.setToUser(user);

            templateMessage.setTemplateId(template.getTemplate_id());
            templateMessage.setUrl(template.getUrl());
            for (int i=0;i<template.data.size();i++){
                WxTemplateItem item = template.getData().get(i);
                List<WxMpTemplateData> data = templateMessage.getData();
                if(data == null){
                    data = new ArrayList<>();
                    templateMessage.setData(data);
                }
                data.add(new WxMpTemplateData(item.getName(), item.getValue(), item.getColor()));
            }

            try {
                String ret = null;

                if(StringUtils.isEmpty(forceAppId) || StringUtils.isEmpty(forceAppSecret)) {
                    ret = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
                }else{
                    vipWxService.makeVIPAppIdValid(forceAppId, forceAppSecret);
                    ret = vipWxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
                }

                log.info("msg send result ::: " + ret);
                errList.add(ret);
            } catch (WxErrorException e) {
                e.printStackTrace();
                errList.add("");
            }
        }

        return errList;
    }
}
